import json

from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from rest_framework import status
from django.conf import settings
import os
from alipay import AliPay, AliPayConfig
from cinema.models import Cinema
from pay.models import Pay
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from pay.utils.uuid_int_util import string_or_int_to_uuid_int

base_dir = os.path.dirname(os.path.abspath(__file__))
app_private_key_path = os.path.join(base_dir, 'keys', 'app_private_key.pem')
alipay_public_key_path = os.path.join(base_dir, 'keys', 'alipay_public_key.pem')


def get_alipay_client():
    with open(app_private_key_path) as f:
        app_private_key_string = f.read()
        f.close()
    with open(alipay_public_key_path) as f:
        alipay_public_key_string = f.read()
        f.close()
    return AliPay(
        appid=settings.ALIPAY_APPID,
        app_notify_url=None,
        app_private_key_string=app_private_key_string,
        alipay_public_key_string=alipay_public_key_string,
        sign_type="RSA2",
        debug=True,
        # config=AliPayConfig(timeout=15),
    )


@api_view(['GET'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
def payView(request, cinema_id):
    # ALIPAY_RETURN_URL = 'https://baidu.com'
    try:
        params = request.GET
        user = request.user  # 这里就是当前认证的用户
        # 将获取到的阐述转为字典类型
        params_dict = params.dict()
        totalPrice = 0
        ids_str = params_dict.get("ids").split(',')
        ids_int = []
        for id_str in ids_str:
            ids_int.append(int(id_str))
        cinema = Cinema.objects.filter(id=cinema_id)
        seat = json.loads(cinema[0].seat)

        for i_dict in seat:
            seat_id = i_dict.get('id')
            if seat_id in ids_int:
                totalPrice += i_dict.get('price')

        alipay = get_alipay_client()

        order_qs = alipay.api_alipay_trade_page_pay(
            out_trade_no=str(cinema_id)+ '-' + str(user.id),
            total_amount=totalPrice,
            subject=f'影票随购 {cinema_id} - {user.username}',
            return_url=None,
            product_code="FAST_INSTANT_TRADE_PAY",
        )

        pay_url = f"{settings.ALIPAY_GATEWAY}?{order_qs}"
        # return redirect(pay_url)  # 直接 302 跳转
        return Response({
            'state': 200,
            'msg': '操作成功',
            'data': pay_url
        })
    except Exception as e:
        return Response({
            'state': 500,
            'msg': f'操作失败: {e}',
            'data': None
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
def pay_result(request):
    try:
        # 拿到请求参数
        params = request.GET
        print('params->', params)
        # 将获取到的阐述转为字典类型
        params_dict = params.dict()
        print('params_dict->', params_dict)
        totalPrice = 0

        cinema_id = int(params_dict.get("cinemaId"))
        # print(cinema_id)
        ids_str = params_dict.get("ids").split(',')
        ids_int = []
        for id_str in ids_str:
            ids_int.append(int(id_str))
        cinema = Cinema.objects.filter(id=cinema_id)
        seat = json.loads(cinema[0].seat)

        # 这里保存的pay_id是字段
        pay = Pay.objects.create(pay_id=str(string_or_int_to_uuid_int(ids_int)), seat_id=ids_str, cinema_id=cinema_id)
        for i_dict in seat:
            seat_id = i_dict.get('id')
            if seat_id in ids_int:
                # 修改其中一个值
                i_dict['payId'] = pay.id
                totalPrice += i_dict.get('price')
                # 重新赋值
                seat[seat_id] = i_dict

        # print(seat)
        seat_dumps = json.dumps(seat, ensure_ascii=False)
        # 支付成功后更新支付后的座位数据
        cinema.update(seat=seat_dumps)

        # 如果验证成功 对数据进行处理
        return Response({
            'state': 200,
            'msg': '操作成功',
            'data': {
                "totalPrice": totalPrice,
                "orderId": str(string_or_int_to_uuid_int(ids_int)),
                "orderTime": pay.created_at
            }
        })
    except Exception as e:
        return Response({
            'state': 500,
            'msg': f'操作失败: {e}',
            'data': None
        })
